package com.ocr.demo;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.sun.deploy.util.StringUtils;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Base64;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class OcrUtils {
    //本机部署的api地址
    private static final String apiUrl = "http://10.0.0.22:8866/predict/ch_pp-ocrv3";
    private static String JsonRed(String message){

        System.out.println(message);
        JSONObject jsonObject = JSONUtil.parseObj(message);
        JSONArray results = jsonObject.getJSONArray("results");
        JSONObject datas = results.getJSONObject(0);
        JSONArray datalist = datas.getJSONArray("data");
        //包装新的json格式
        JSONObject jnewData = new JSONObject();
        jnewData.set("address_key","lvalue");
        jnewData.set("idNumber_key","lvalue");

        StringBuilder stringBuilderAll= new StringBuilder();
        for (int i = 0; i < datalist.size(); i++) {
            String lvalue = datalist.getJSONObject(i).getStr("text");
            stringBuilderAll.append(lvalue);
            //解析身份证信息
            JSONObject one=analysisIdCard(lvalue);

            for (String key: one.keySet()
                 ) {
                jnewData.set(key,one.get(key));
            }
        }
        //地址
        jnewData.set("address",indexOf(stringBuilderAll.toString(),jnewData.getStr("address_key"),jnewData.getStr("idNumber_key")).replace("勋阳区","郧阳区"));

        jnewData.remove("address_key");
        jnewData.remove("idNumber_key");
        return jnewData.toString();
    }


    public static String indexOf(String str1,String str2,String str3) {


        int startIndex = str1.indexOf(str2);
        if (startIndex != -1) {
            startIndex += str2.length(); // 跳过起始字符串
            int endIndex = str1.indexOf(str3, startIndex);
            if (endIndex != -1) {
                String result = str1.substring(startIndex, endIndex);
                return result;
            }
        }
        return "non";
    }
    /**
     * 识别身份证信息
     *
     * @param lvalue
     * @return cf 返回key 和值
     */
    public static JSONObject analysisIdCard(String lvalue) {

        JSONObject rootJson= new JSONObject();

        String rowvalue="non";

        if (lvalue == null) {
            rootJson.set("non","non");
        }
        boolean isok=false;
        try {
            InputStream inputStream = CS.class.getClassLoader().getResourceAsStream("hot.properties");
            Properties properties = new Properties();
            properties.load(inputStream);

            //找出地址 和身份证号 准确文字
            for (String key : properties.stringPropertyNames()) {
                String value = properties.getProperty(key);
                value = new String(value.getBytes("ISO-8859-1"), "UTF-8");
                for (String v:value.split(",")
                ) {
                    if(key.equals("address")&&lvalue.contains(v) ){
                        rootJson.set("address_key",lvalue);
                    }

                    if(key.equals("idNumber")&&lvalue.contains(v) ){
                        rootJson.set("idNumber_key",lvalue);
                    }
                }
            }
            //适合处理 姓名 出生 性别 名族
            outerloop: // 标记外层循环
            for (String key : properties.stringPropertyNames()) {
                String value = properties.getProperty(key);
                value = new String(value.getBytes("ISO-8859-1"), "UTF-8");
               // System.out.println("Key: " + key + ", Value: " + value);
                innerloop: // 标记内层循环
                for (String v:value.split(",")
                     ) {
                    //民族处理
                    if(key.equals("nation")&&lvalue.contains(v) ){
                        try {
                            rowvalue =lvalue.split(v)[1];
                        }catch (Exception e){
                            rowvalue ="err";
                        }
                        rootJson.set(key,rowvalue);
                    }
                    if(lvalue.startsWith(v) ){
                        //如果是性别取一位
                        rowvalue = lvalue.replace(v, "");
                        if(key.equals("sex")){
                            rowvalue =lvalue.replace(v, "").substring(0, 1);
                        }
                        rootJson.set(key,rowvalue);
                        isok=true;
                        break outerloop; // 跳出外层循环

                    }
                }
            }
            //处理证件号
            // 创建正则表达式模式匹配数字
            Pattern pattern = Pattern.compile("\\d+");
            Matcher matcher = pattern.matcher(lvalue);

            // 循环匹配并提取数字
            while (matcher.find()) {
                String numberStr = matcher.group();
                if(numberStr.length()>16){
                    isok=true;
                    rootJson.set("idNumber",numberStr);
                }
            }

            if(!isok){
                rootJson.set("non","non");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return rootJson;
    }

    /**
     * @param imageFile       图片文件
     * @param compressQuality 压缩质量设置为0 - 1（最低质量 - 最高质量）
     * @return
     */
    public static String post(File imageFile, float compressQuality) {
        try {
            System.out.println("开始处理图片格式");
            long startTime = System.currentTimeMillis();
            // 读取图像文件
            BufferedImage image = ImageIO.read(imageFile);
            // 创建新的BufferedImage对象，并指定宽度、高度和颜色类型（这里选择RGB）
            BufferedImage jpegImage = new BufferedImage(image.getWidth(), image.getHeight(),
                    BufferedImage.TYPE_INT_RGB);
            // 将PNG图片绘制到新的BufferedImage对象中
            jpegImage.createGraphics().drawImage(image, 0, 0, null);
            // 创建字节数组输出流
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            // 将图像数据编码为JPEG格式并写入输出流
            ImageIO.write(jpegImage, "jpeg", outputStream);

            InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
            BufferedImage jpgimage = ImageIO.read(inputStream);
            //是否压缩
            try {
                long endTime = System.currentTimeMillis();
                long executionTime = endTime - startTime;
                System.out.println("图片格式处理完成！用时" + executionTime);
                //     return yasuo(jpgimage,compressQuality);
              //  return getBase64(outputStream, null);
                return JsonRed(getBase64(outputStream, null));
            } catch (Exception e) {
                e.printStackTrace();
                return "";
            }

        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }

    private static String getBase64(ByteArrayOutputStream outputStream, ImageWriter writer) throws Exception {
        // 获取编码后的图像数据
        byte[] encodedData = outputStream.toByteArray();
        // 进行Base64编码
        byte[] encodedDatabm = Base64.getEncoder().encode(encodedData);
        String encodedString = new String(encodedDatabm);
        // 关闭输出流
        outputStream.close();
        if (writer != null) {
            writer.dispose();
        }
        // 打印编码后的图像数据
        //请求json体
        String param = "{\"images\":[\"" + encodedString + " \"]}";

        return HttpUtil.post(apiUrl, param);
    }

    /**
     * @param image
     * @param compressQuality 压缩质量设置为0 - 1（最低质量 - 最高质量）
     * @return
     */
    public static String yasuo(BufferedImage image, float compressQuality) {


        try {
            System.out.println("开始压缩");
            long startTime = System.currentTimeMillis();
            // 获取图像编码器
            ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next();
            // 设置压缩参数
            ImageWriteParam param = writer.getDefaultWriteParam();
            param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
            param.setCompressionQuality(compressQuality);

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            // 将压缩后的图像写入输出流
            writer.setOutput(ImageIO.createImageOutputStream(outputStream));
            writer.write(null, new IIOImage(image, null, null), param);
            long endTime = System.currentTimeMillis();
            long executionTime = endTime - startTime;
            System.out.println("图片压缩完成！用时" + executionTime);
            try {

                return getBase64(outputStream, writer);
            } catch (Exception e) {
                return "";
            }

        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 直接压缩文件
     *
     * @param imagef          图片文件
     * @param compressQuality 压缩质量设置为0 - 1（最低质量 - 最高质量）
     * @return
     */
    public static String yasuo(File imagef, float compressQuality) {

        try {
            BufferedImage image = ImageIO.read(imagef);
            System.out.println("开始压缩");
            long startTime = System.currentTimeMillis();
            // 获取图像编码器
            ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next();
            // 设置压缩参数
            ImageWriteParam param = writer.getDefaultWriteParam();
            param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
            param.setCompressionQuality(compressQuality);

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            // 将压缩后的图像写入输出流
            writer.setOutput(ImageIO.createImageOutputStream(outputStream));
            writer.write(null, new IIOImage(image, null, null), param);
            long endTime = System.currentTimeMillis();
            long executionTime = endTime - startTime;
            System.out.println("图片压缩完成！用时" + executionTime);
            try {
                return getBase64(outputStream, writer);
            } catch (Exception e) {
                return "";
            }

        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }
}
